﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;

namespace RouterControl.LocalDb
{
    partial class LocalDbConnector
    {
        public struct DeviceInfo
        {
            public int Id;
            public string DeviceId;
            public string DeviceType;
        }

        public DeviceInfo? GetDeviceInfo(string uniqueId)
        {
            if (string.IsNullOrEmpty(uniqueId))
                throw new ArgumentException("null or empty", "uniqueId");

            try
            {
	            // query data
	            var cmd = _db.CreateCommand();
	
	            cmd.CommandText = "select Id,DeviceId,DeviceType from Devices where DeviceId like @id limit 1";
	            cmd.Parameters.AddWithValue("@id", uniqueId);
	
	            // read data
	            using (var r = cmd.ExecuteReader())
	            {
	                if (!r.Read())
	                    return null;
	
	                return new DeviceInfo()
	                {
	                    Id = r.GetInt32(0),
	                    DeviceId = r.GetString(1),
	                    DeviceType = r.GetString(2)
	                };
	            }
            }
            catch (Exception ex)
            {
                _log.Error("Local DB failed: GetDeviceInfo()", ex);

                throw;
            }
        }

        public void DeleteDevice(DeviceInfo dev)
        {
            if (dev.Id <= 0)
                throw new ArgumentException("invalid device", "dev");

            try
            {
                var cmd = _db.CreateCommand();

                cmd.CommandText = "delete from Devices where Id=@id";
                cmd.Parameters.AddWithValue("@id", dev.Id);

                cmd.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                _log.Error("Local DB failed: DeleteDevice()", ex);

                throw;
            }
        }

        public void DeleteAllDevicesExcept(DeviceInfo dev)
        {
            if (dev.Id <= 0)
                throw new ArgumentException("invalid device", "dev");

            try
            {
                var cmd = _db.CreateCommand();

                cmd.CommandText = "delete from Devices where Id!=@id";
                cmd.Parameters.AddWithValue("@id", dev.Id);

                cmd.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                _log.Error("Local DB failed: DeleteDevice()", ex);

                throw;
            }
        }

        public DeviceInfo EnsureDevice(string uniqueId, string deviceType)
        {
            var dev = GetDeviceInfo(uniqueId);

            if (dev.HasValue)
                return dev.Value;

            return RegisterDevice(uniqueId, deviceType);
        }

        public DeviceInfo RegisterDevice(string uniqueId, string deviceType)
        {
            if (string.IsNullOrEmpty(uniqueId))
                throw new ArgumentException("null or empty", "uniqueId");

            if (string.IsNullOrEmpty(deviceType))
                throw new ArgumentException("null or empty", "deviceType");

            try
            {
	            // query data
	            var cmd = _db.CreateCommand();
	
	            cmd.CommandText = "insert into Devices (DeviceId,DeviceType) values (@id,@t); select last_insert_rowid()";
	            cmd.Parameters.AddWithValue("@id", uniqueId);
	            cmd.Parameters.AddWithValue("@t", deviceType);
	            
	            // insert
	            var id = Convert.ToInt32(cmd.ExecuteScalar());
	
	            return new DeviceInfo()
	            {
	                Id = id,
	                DeviceId = uniqueId,
	                DeviceType = deviceType
	            };
            }
            catch (Exception ex)
            {
                _log.Error("Local DB failed: RegisterDevice()", ex);

                throw;
            }
        }

    }
}
